package com.hospital.service.project.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.hospital.service.project.model.vo.ProInfoBaseVo3;
import com.hospital.service.publics.entity.PubUserInfo;
import com.hospital.service.publics.service.PubFilePathService;
import com.hospital.service.publics.service.PubUserInfoService;
import common.core.entity.ProImportSonEntity;
import common.core.entity.ProjectEntity;
import common.core.entity.ProjectImportSuperEntity;
import com.hospital.service.project.entity.help.ProInfoBaseHelp;
import com.hospital.service.project.model.param.*;
import com.hospital.service.project.model.vo.ProInfoBaseVo;
import com.hospital.service.project.service.ProInfoDetailsService;
import common.core.constant.Constant;
import enhance.plus.logic.LogicBaseServiceImpl;
import com.hospital.service.project.entity.ProInfoBase;
import com.hospital.service.project.mapper.ProInfoBaseMapper;
import com.hospital.service.project.service.ProInfoBaseService;
import enhance.plus.util.Page;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import common.core.util.*;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.util.List;

/**
 * 实验项目基本表 接口
 *
 * @author xhl
 * @created 2020-10-10 13:58:34
 */
@SuppressWarnings("all")
@Slf4j
@Service
public class ProInfoBaseServiceImpl extends LogicBaseServiceImpl<ProInfoBaseMapper, ProInfoBase> implements ProInfoBaseService {


    @Autowired
    private ProInfoDetailsService proInfoDetailsService;

    @Autowired
    private ProInfoBaseMapper proInfoBaseMapper;

    @Autowired
    private PubUserInfoService pubUserInfoService;

    @Autowired
    private PubFilePathService pubFilePathService;

    /**
     * 新增实验项目
     *
     * @param param
     */
    @Override
    public void save(ProInfoBaseParam param) {
        if (checkExit(param.getProjectNumber())) {
            throw CustomizeRuntimeException.exception("编号已存在");
        }
        ProInfoBase proInfoBase = CommonUtil.copyBean(param, ProInfoBase.class);
        this.save(proInfoBase);
        pubFilePathService.fileCreate(param.getProjectNumber(), null);
    }



    /**
     * 新增子实验项目
     *
     * @param param
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void save(ProInfoBaseSaveSonParam param) {
        if (checkExit(param.getProjectNumber())) {
            throw CustomizeRuntimeException.exception("编号已存在");
        }
        log.info("1. 将此条信息插入项目基本表");
        this.save(CommonUtil.copyBean(param, ProInfoBase.class));
        log.info("2. 维护详细表");
        List<String> implementerNumbers = param.getImplementerNumbers();
        if (CommonUtil.isNotEmpty(implementerNumbers)) {
            proInfoDetailsService.saveItem(param.getProjectNumber(), implementerNumbers);
        }
        pubFilePathService.fileCreate(param.getProjectNumber(), param.getSuperiorProjectNumber());
    }

    /**
     * 生成项目检索编号
     *
     * @param isParent true：父项目 false：子项目
     * @return
     */
    @Override
    public String itemGenerate(boolean isParent) {
        log.info("根据项目类型来设置项目检索编号");
        int max;
        if (isParent) {
            String maxProjectNumber = this.proInfoBaseMapper.getMaxProjectNumber(Constant.PARENT_PROJECT_PREFIX + "%");
            if (CommonUtil.isEmpty(maxProjectNumber)) {
                return Constant.PARENT_PROJECT_PREFIX + "000001";
            }
            String suffix = "00000" + (new Integer(maxProjectNumber.substring(3)) + 1);
            return Constant.PARENT_PROJECT_PREFIX + suffix.substring(suffix.length() - 6);
        } else {
            String maxProjectNumber = this.proInfoBaseMapper.getMaxProjectNumber(Constant.SUB_PROJECT_PREFIX + "%");
            if (CommonUtil.isEmpty(maxProjectNumber)) {
                return Constant.SUB_PROJECT_PREFIX + "000001";
            }
            String suffix = "00000" + (new Integer(maxProjectNumber.substring(3)) + 1);
            return Constant.SUB_PROJECT_PREFIX + suffix.substring(suffix.length() - 6);
        }
    }

    @Override
    public String getCode(String formName,String prefix,String field) {
        int max;
        String maxNumber = this.proInfoBaseMapper.getMaxNumberOther(formName,field,prefix + "%");
        if (CommonUtil.isEmpty(maxNumber)) {
            return prefix + "000001";
        }
        String suffix = "00000" + (new Integer(maxNumber.substring(3)) + 1);
        return prefix + suffix.substring(suffix.length() - 6);
    }

    /**
     * 修改项目信息
     *
     * @param param
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void updateProject(ProInfoBaseUpdateParam param) {
        if (CommonUtil.isEmpty(param)) {
            throw CustomizeRuntimeException.exception("传入参数为空");
        }
        log.info("更新项目基本信息");
        UpdateWrapper<ProInfoBase> updateWrapper = ProInfoBaseHelp.createUpdate();
        updateWrapper.eq(ProInfoBaseHelp.projectNumber, param.getProjectNumber());
        this.update(CommonUtil.copyBean(param, ProInfoBase.class), updateWrapper);

        log.info("子项目修改信息， 还需修改中间表信息");
        if (CommonUtil.isNotEmpty(param.getImplementerNumbers())) {
            proInfoDetailsService.updateMessage(param.getProjectNumber(), param.getImplementerNumbers());
        }
    }

    /**
     * 查询一条数据
     *
     * @param param
     * @return
     */
    @Override
    public ProInfoBaseVo queryForOneRow(ProInfoBaseQueryForOneRowParam param) {
        if (CommonUtil.isEmpty(param)) {
            throw CustomizeRuntimeException.exception("传入的参数为空");
        }
        ProInfoBaseVo proInfoBaseVo = proInfoBaseMapper.queryOne(param.getProjectNumber());
        String chargePerson = proInfoBaseVo.getChargePerson();

        if (CommonUtil.isEmpty(chargePerson)) {
            return proInfoBaseVo;
        }
        log.debug("将负责人的相关信息插入返回值之中");
        PubUserInfo userInfo = pubUserInfoService.queryUser(chargePerson);
        if (CommonUtil.isNotEmpty(userInfo)) {
            proInfoBaseVo.setUserId(userInfo.getId());
            proInfoBaseVo.setEmail(userInfo.getEmail());
            proInfoBaseVo.setPhone(userInfo.getPhone());
        }
        return proInfoBaseVo;
    }

    /**
     * 分页查询项目
     *
     * @param param
     * @return
     */
    @Override
    public Page<ProInfoBaseVo> queryPage(ProInfoBaseQueryPageParam param) {
        if (CommonUtil.isEmpty(param)) {
            throw CustomizeRuntimeException.exception("传入的参数为空");
        }
        log.debug("得到父项目的数量");
        QueryWrapper<ProInfoBase> query = ProInfoBaseHelp.createQuery();
        query.isNull(ProInfoBaseHelp.superiorProjectNumber);
        int count = this.count(query);

        log.debug("得到分页的数据");
        List<ProInfoBaseVo> records = proInfoBaseMapper.queryPage(param, param.getCurrent() * param.getSize());
        for (ProInfoBaseVo record : records) {
            String chargePerson = record.getChargePerson();
            if (CommonUtil.isEmpty(chargePerson)) {
                continue;
            }
            PubUserInfo userInfo = pubUserInfoService.queryUser(chargePerson);
            if (CommonUtil.isEmpty(userInfo)) {
                continue;
            }
            record.setPhone(userInfo.getPhone());
            record.setEmail(userInfo.getEmail());
        }
        Page<ProInfoBaseVo> voPage = new Page<>(param.getCurrent(), param.getSize());
        voPage.setTotal(count);
        voPage.setRecords(records);
        return voPage;
    }

    /**
     * 批量删除项目
     *
     * @param param
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void removeProject(ProInfoBaseDeleteParam param) {
        if (CommonUtil.isEmpty(param)) {
            throw CustomizeRuntimeException.exception("传入的参数为空");
        }
        QueryWrapper<ProInfoBase> query = ProInfoBaseHelp.createQuery();
        query.eq(ProInfoBaseHelp.projectNumber, param.getProjectNumbers());
        this.remove(query);
        // 逻辑删除文件连接
        pubFilePathService.deleteFile(param.getProjectNumbers());
    }

    /**
     * 文件项目导出
     *
     * @param param
     */
    @Override
    public void projectExport(ProjectExportParam param, HttpServletResponse response) {
        log.debug("找到此条数据");
        if (CommonUtil.isEmpty(param)) {
            throw CustomizeRuntimeException.exception("传入的参数为空");
        }
        List<ProjectImportSuperEntity> list = this.proInfoBaseMapper.getData(param.getProjectNumberList());
        String title = "实验项目信息";
        try {
            ExcelUtil.exportExcel(list, title, title, ProjectImportSuperEntity.class, title + ".xls", response);
        } catch (Exception e) {
            throw CustomizeRuntimeException.exception("信息导出失败");
        }
    }

    /**
     * 父项目excel文件导入
     *
     * @param file
     */
    @Override
    public void importSuperProject(MultipartFile file) {
        log.debug("判断文件的格式是否是excel文件");
        if (!ExcelUtil.isExcel(file)) {
            throw CustomizeRuntimeException.exception("传入的文件格式不是excel");
        }

        log.info("读取文件中的内容，并存入实体类中");
        List<ProjectEntity> projectEntities = null;
        try {
            projectEntities = ExcelUtil.importExcel(file, 0, 1, ProjectEntity.class);
        } catch (Exception e) {
            throw CustomizeRuntimeException.exception("文件上传失败");
        }

        log.debug("将数据存入数据库");
        for (ProjectEntity projectEntity : projectEntities) {
            if (CommonUtil.isEmpty(projectEntity)) {
                continue;
            }

            // 设置项目编号
            String itemGenerate = this.itemGenerate(true);
            ProInfoBaseParam proInfoBaseParam = CommonUtil.copyBean(projectEntity, ProInfoBaseParam.class);
            proInfoBaseParam.setChargePerson(projectEntity.getUserInfoEntity().getUserNumber());
            proInfoBaseParam.setProjectNumber(itemGenerate);
            this.save(proInfoBaseParam);
        }
    }

    /**
     * 导入子项目
     *
     * @param file
     */
    @Override
    public void importSonProject(MultipartFile file) {
        log.debug("判断文件的格式是否是excel文件");
        if (!ExcelUtil.isExcel(file)) {
            throw CustomizeRuntimeException.exception("传入的文件格式不是excel");
        }

        log.info("读取文件中的内容，并存入实体类中");
        List<ProImportSonEntity> proImportSonEntities = null;
        try {
            proImportSonEntities = ExcelUtil.importExcel(file, 0, 2, ProImportSonEntity.class);
        } catch (Exception e) {
            throw CustomizeRuntimeException.exception("文件上传失败");
        }

        log.debug("开始处理相关数据");
        for (ProImportSonEntity projectImportSonEntity : proImportSonEntities) {
            if (CommonUtil.isEmpty(projectImportSonEntity)) {
                continue;
            }

            ProInfoBaseSaveSonParam proInfoBaseSaveSonParam = CommonUtil.copyBean(projectImportSonEntity, ProInfoBaseSaveSonParam.class);

            this.save(proInfoBaseSaveSonParam);
        }
    }

    /**
     * 查询子项目的基本信息
     *
     * @param param
     * @return
     */
    @Override
    public ProInfoBaseVo3 querySonMessage(ProInfoBaseQueryForOneRowParam param) {
        if (CommonUtil.isEmpty(param.getProjectNumber())) {
            throw CustomizeRuntimeException.exception("传入的参数为空");
        }
        log.debug("先查询次子项目的基本信息");
        QueryWrapper<ProInfoBase> query = ProInfoBaseHelp.createQuery();
        query.eq(ProInfoBaseHelp.projectNumber, param.getProjectNumber());
        ProInfoBase one = this.getOne(query);
        if (CommonUtil.isEmpty(one)) {
            throw CustomizeRuntimeException.exception("没有此条信息");
        }

        return this.proInfoBaseMapper.querySonMessage(param);
    }

    /**
     * 判断编号是否存在
     *
     * @param projectNumber
     * @return
     */
    private boolean checkExit(String projectNumber) {
        QueryWrapper<ProInfoBase> query = ProInfoBaseHelp.createQuery();
        query.eq(ProInfoBaseHelp.projectNumber, projectNumber);
        int count = this.count(query);
        return count > 0;
    }
}
